#include <winsock2.h>
#include <Windows.h>
#include "common.h"
#include "comdef.h"

void my_sleep( unsigned long nSecord)
{
#ifdef WIN32
	Sleep(nSecord);
#endif
}

unsigned long my_GetLastError()
{
	return GetLastError();
}

char *GetIpAddressBySock(int nScokId, int &nPort)
{
	struct sockaddr_in peeraddr;
	socklen_t len = sizeof(sockaddr_in);
	int ret = getpeername(nScokId, (struct sockaddr *)&peeraddr, &len);
	if (ret >= 0)
	{
		nPort = ntohs(peeraddr.sin_port);
		return inet_ntoa(peeraddr.sin_addr);
	}
	else
	{	
		return NULL;
	}
}

unsigned long GetTimeStamp(void)
{
	return GetTickCount();
}

void GetTime(char *pBuf)
{
	time_t nt;
	time(&nt);

	struct tm *local;	
	local = localtime(&nt);
	sprintf(pBuf,"%d-%02d-%02d %02d:%02d:%02d",local->tm_year + 1900 ,
		local->tm_mon + 1,
		local->tm_mday,
		local->tm_hour,
		local->tm_min,
		local->tm_sec);
}

void GetTimeEx(char *pBuf)
{
	time_t nt;
	time(&nt);

	struct tm *local;	
	local = localtime(&nt);
	sprintf(pBuf,"%d%02d%02d",local->tm_year + 1900 ,
		local->tm_mon + 1,
		local->tm_mday);
}

int CheckBuf(char *pData, unsigned int nDataLen, int &nCmd, int &nSendId, int &nPacketNum, int &nPacketLen)
{
	if (!pData)
		return -1;
	
	if (nDataLen < HEADER_PACKET_LEN)
		return -1;

	char *pBuf = pData;
	int pos = 0;
	int size = nDataLen - HEADER_PACKET_LEN;
	while (pos <= size)
	{
		MsgPacketHeader *p = (MsgPacketHeader *)pBuf;
		if (p->ulHtag == MSG_TAG_HEADER)
		{
			if (p->ulMsgLen <= nDataLen)
			{
				nCmd = p->usMsgType;
				nSendId = p->ulSenderId;
				nPacketNum = p->usSeqNo;
				nPacketLen = p->ulMsgLen;
				return pos;
			}
			else
				return -1;
		}

		pBuf++;
		pos++;
	}

	return -1;
}

int Utf8ToGBK(const char* strUtf8, int nLen, char *outBuf, int &nBuffLen)
{
	int nRet = -1;

	int len=MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, NULL,0); 
	unsigned short * wszGBK = new unsigned short[len+1];       
	memset(wszGBK, 0, len * 2 + 2); 
	MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, (LPWSTR)wszGBK, len);
	len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wszGBK, -1, NULL, 0, NULL, NULL);
	char *szGBK=new char[len + 1]; 
	memset(szGBK, 0, len + 1); 
	WideCharToMultiByte (CP_ACP, 0, (LPCWSTR)wszGBK, -1, (LPSTR)szGBK, len, NULL,NULL);

	if (nBuffLen >= (len + 1))
	{
		memcpy(outBuf, szGBK, len + 1);
		nRet = len + 1;
	}
	else
	{
		nBuffLen = len + 1;
		nRet = 0;
	}

	delete [] wszGBK;
	delete [] szGBK;

	return nRet;
}

int GBKToUtf8(const char* strGBK, int nLen, char *outBuf, int &nBuffLen)
{ 
	int nRet = -1;

	int len=MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, NULL,0); 
	unsigned short * wszUtf8 = new unsigned short[len+1]; 
	memset(wszUtf8, 0, len * 2 + 2); 
	MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, (LPWSTR)wszUtf8, len);
	len = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)wszUtf8, -1, NULL, 0, NULL, NULL);
	char *szUtf8=new char[len + 1]; 
	memset(szUtf8, 0, len + 1); 
	WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR)wszUtf8, -1, (LPSTR)szUtf8, len, NULL,NULL);
	
	if (nBuffLen >= (len + 1))
	{
		memcpy(outBuf, szUtf8, len + 1);
		nRet = len + 1;
	}
	else
	{
		nBuffLen = len + 1;
		nRet = 0;
	}

	delete [] wszUtf8;
	delete [] szUtf8;
	
	return nRet;
}

bool CreateDir(const char *pszDirName)
{
	if (!pszDirName)
		return false;

#ifdef WIN32
	char  szDir[MAX_PATH] = { 0 };
	char  szTmp[MAX_PATH] = { 0 };
	int  nLen = 0;
	int  idx;

	memcpy(szDir, pszDirName, MAX_PATH);
	nLen = strlen(szDir);

	if (szDir[nLen - 1] == '\\' || szDir[nLen - 1] == '/')
		szDir[nLen - 1] = '\0';

	nLen = strlen(szDir);
	char  str[2] = { 0 };

	for (idx = 0; idx < nLen; idx++)
	{
		if (szDir[idx] != '\\')
		{
			str[0] = szDir[idx];
			str[1] = 0;
			strcat(szTmp, str);
		}
		else
		{
			BOOL bRet = ::CreateDirectory(szTmp, NULL);
			if (bRet)
				::SetFileAttributes(szTmp, FILE_ATTRIBUTE_NORMAL);

			str[0] = szDir[idx];
			str[1] = 0;
			strcat(szTmp, str);
		}

		if (idx == nLen - 1)
		{
			BOOL bRet = ::CreateDirectory(szTmp, NULL);
			if (bRet)
				::SetFileAttributes(szTmp, FILE_ATTRIBUTE_NORMAL);
		}
	}

	if (DirExist(szTmp))
		return true;
#endif
	return false;
}

bool DirExist(const char *pszDirName)
{
	if (!pszDirName)
		return false;

#ifdef _WIN32
	WIN32_FIND_DATA fileinfo;
	char	szDir[MAX_PATH] = { 0 };

	memcpy(szDir, pszDirName, MAX_PATH);
	int nLen = lstrlen(szDir);

	if ((szDir[nLen - 1] == '\\') || (szDir[nLen - 1] == '/'))
		szDir[nLen - 1] = '\0';

	HANDLE	hFind = ::FindFirstFile(szDir, &fileinfo);

	if (hFind == INVALID_HANDLE_VALUE)
		return FALSE;

	if (fileinfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
	{
		::FindClose(hFind);
		return true;
	}

	::FindClose(hFind);

#endif
	return false;
}
